﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace WJP.Dependency
{
    /// <summary>
    /// 为类定义接口，用于注册依赖项。
    /// </summary>
    public interface IIocRegistrar
    {
        /// <summary>
        /// 添加约定注册提供者，IOC容器会根据约定注册类注册程序集所有符合约定的对象
        /// <para>比如<see cref="BasicConventionalRegistrar"/>会注册所有实现了IInterceptor、ITransientDependency和ISingletonDependency的对象</para>
        /// </summary>
        /// <param name="registrar">依赖注册</param>
        void AddConventionalRegistrar(IConventionalDependencyRegistrar registrar);

        /// <summary>
        /// 添加要用所有约定注册进行注册的程序集
        /// </summary>
        /// <param name="assembly">要用于注册的程序集</param>
        void RegisterAssemblyByConvention(Assembly assembly);

        /// <summary>
        /// 添加要用所有约定注册进行注册的程序集
        /// </summary>
        /// <param name="assembly">要用于注册的程序集</param>
        /// <param name="config">约定注册配置</param>
        void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config);

        /// <summary>
        /// 将类型注册为自注册
        /// </summary>
        /// <typeparam name="T">类的类型</typeparam>
        /// <param name="lifeStyle">这个类型的生命周期，默认为单例模式</param>
        void Register<T>(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
            where T : class;

        /// <summary>
        /// 将类型注册为自注册
        /// </summary>
        /// <typeparam name="T">类的类型</typeparam>
        /// <param name="key">组件的名称</param>
        /// <param name="lifeStyle">这个类型的生命周期，默认为单例模式</param>
        void Register<T>(string key, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
            where T : class;

        /// <summary>
        /// 将类型注册为自注册
        /// </summary>
        /// <param name="type">类的类型</param>
        /// <param name="lifeStyle">这个类型的生命周期，默认为单例模式</param>
        void Register(Type type, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton);

        /// <summary>
        /// 将类型注册为自注册
        /// </summary>
        /// <param name="key">组件的名称</param>
        /// <param name="type">类的类型</param>
        /// <param name="lifeStyle">这个类型的生命周期，默认为单例模式</param>
        void Register(string key, Type type, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton);

        /// <summary>
        /// 向类型的实现注册类型
        /// </summary>
        /// <typeparam name="TType">注册类型</typeparam>
        /// <typeparam name="TImpl">类型<typeparamref name="TType"/>的实现类</typeparam>
        /// <param name="lifeStyle">这个类型的生命周期，默认为单例模式</param>
        void Register<TType, TImpl>(DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
            where TType : class
            where TImpl : class, TType;

        /// <summary>
        /// 向类型的实现注册类型
        /// </summary>
        /// <typeparam name="TType">注册类型</typeparam>
        /// <typeparam name="TImpl">类型<typeparamref name="TType"/>的实现类</typeparam>
        /// <param name="key">组件的名称</param>
        /// <param name="lifeStyle">这个类型的生命周期，默认为单例模式</param>
        void Register<TType, TImpl>(string key, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton)
            where TType : class
            where TImpl : class, TType;

        /// <summary>
        /// 向类型的实现注册类型
        /// </summary>
        /// <param name="type">注册类型</param>
        /// <param name="impl">类型<paramref name="type"/>的实现类</param>
        /// <param name="lifeStyle">这个类型的生命周期，默认为单例模式</param>
        void Register(Type type, Type impl, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton);

        /// <summary>
        /// 向类型的实现注册类型
        /// </summary>
        /// <param name="key">组件的名称</param>
        /// <param name="type">注册类型</param>
        /// <param name="impl">类型<paramref name="type"/>的实现类</param>
        /// <param name="lifeStyle">这个类型的生命周期，默认为单例模式</param>
        void Register(string key, Type type, Type impl, DependencyLifeStyle lifeStyle = DependencyLifeStyle.Singleton);

        /// <summary>
        /// 检查之前是否注册了给定的类型
        /// </summary>
        /// <typeparam name="TType">要检查的类型</typeparam>
        /// <returns></returns>
        bool IsRegistered<TType>();

        /// <summary>
        /// 检查之前是否注册了给定的类型
        /// </summary>
        /// <param name="type">要检查的类型</param>
        /// <returns></returns>
        bool IsRegistered(Type type);
    }
}
